﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Collections.Specialized;
using Cielo.API.XML.Helpers;
namespace Cielo.API.XML
{
    internal class ConversorResultadoGatewayXML
    {

        private static RespostaRequisicao ProcessarSucesso(XmlDocument resultXML)
        {
            var respostaRequisicao = new RespostaRequisicao();
            respostaRequisicao.XML = resultXML.OuterXml;

            respostaRequisicao.TransacaoID = resultXML.GetUniqueElementByTagName("tid").InnerText;
            respostaRequisicao.PAN = resultXML.GetUniqueElementByTagName("pan").InnerText;
            respostaRequisicao.Status = resultXML.GetUniqueElementByTagName("status").InnerText;

            var autorizacaoNode = resultXML.GetUniqueElementByTagName("autorizacao");

            respostaRequisicao.Autorizacao.Codigo = autorizacaoNode.GetUniqueElementByTagName("codigo").InnerText;
            respostaRequisicao.Autorizacao.Mensagem = autorizacaoNode.GetUniqueElementByTagName("mensagem").InnerText;
            respostaRequisicao.Autorizacao.DataHora = autorizacaoNode.GetUniqueElementByTagName("data-hora").InnerText;
            respostaRequisicao.Autorizacao.Valor = autorizacaoNode.GetUniqueElementByTagName("valor").InnerText;
            respostaRequisicao.Autorizacao.LR = autorizacaoNode.GetUniqueElementByTagName("lr").InnerText;
            respostaRequisicao.Autorizacao.NSU = autorizacaoNode.GetUniqueElementByTagName("nsu").InnerText;

            var dadosPedidoNode = resultXML.GetUniqueElementByTagName("dados-pedido");
            respostaRequisicao.Pedido.Numero = dadosPedidoNode.GetUniqueElementByTagName("numero").InnerText;
            respostaRequisicao.Pedido.Valor = dadosPedidoNode.GetUniqueElementByTagName("valor").InnerText;
            respostaRequisicao.Pedido.Moeda = dadosPedidoNode.GetUniqueElementByTagName("moeda").InnerText;
            respostaRequisicao.Pedido.DataHora = dadosPedidoNode.GetUniqueElementByTagName("data-hora").InnerText;
            respostaRequisicao.Pedido.Idioma = dadosPedidoNode.GetUniqueElementByTagName("idioma").InnerText;


            var formaPagamentoNode = resultXML.GetUniqueElementByTagName("forma-pagamento");
            respostaRequisicao.FormaPagamento.Bandeira = formaPagamentoNode.GetUniqueElementByTagName("bandeira").InnerText;
            respostaRequisicao.FormaPagamento.TipoProduto = formaPagamentoNode.GetUniqueElementByTagName("produto").InnerText;
            respostaRequisicao.FormaPagamento.Parcelas = formaPagamentoNode.GetUniqueElementByTagName("parcelas").InnerText;

            return respostaRequisicao;
        }
        private static RespostaRequisicao ProcessarErro(XmlDocument resultXML)
        {
            var respostaRequisicao = new RespostaRequisicao();
            var errorNodes = resultXML.GetElementsByTagName("erro");
            if (errorNodes.Count == 1)
            {
                var noErro = (errorNodes[0] as XmlElement);
                var codigoErro = noErro.GetUniqueElementByTagName("codigo").InnerText;
                var mensagemErro = ObterMensagemErro(codigoErro);

                respostaRequisicao.CodigoErro = codigoErro;
                respostaRequisicao.MensagemErro = mensagemErro;
            }
            return respostaRequisicao;
        }
        private static string ObterMensagemErro(string codigoErro)
        {
            var mensagensErro = new NameValueCollection();
            mensagensErro.Add("001", "Mensagem inválida:A mensagem XML está fora do formato especificado pelo arquivo ecommerce.xsd");
            mensagensErro.Add("002", "Credenciais inválidas:Impossibilidade de autenticar uma requisição da loja virtual.");
            mensagensErro.Add("003", "Transação inexistente:Não existe transação para o identificador informado");
            mensagensErro.Add("010", "Inconsistência no envio do cartão:A transação, com ou sem cartão, está divergente com a permissão de envio dessa informação");
            mensagensErro.Add("011", "Modalidade não habilitada:A transação está configurada com uma modalidade de pagamento não habilitada para a loja");
            mensagensErro.Add("012", "Número de parcelas inválido:O número de parcelas solicitado ultrapassa o máximo permitido");
            mensagensErro.Add("013", "Flag de autorização automática inválida:Flag de autorização automática incompatível com a forma de pagamento solicitada");
            mensagensErro.Add("014", "Autorização Direta inválida:A solicitação de Autorização Direta está inválida");
            mensagensErro.Add("015", "Autorização Direta sem Cartão:A solicitação de Autorização Direta está sem cartão");
            mensagensErro.Add("016", "Identificador, TID inválido:O TID fornecido está duplicado");
            mensagensErro.Add("017", "Código de segurança ausente:O código de segurança do cartão não foi enviado");
            mensagensErro.Add("018", "Indicador de código de segurança inconsistente:Uso incorreto do indicador de código de segurança");
            mensagensErro.Add("020", "Status não permite autorização:Não é permitido realizar autorização para o status da transação");
            mensagensErro.Add("021", "Prazo de autorização vencido: Não é permitido realizar autorização, pois o prazo está vencido");
            mensagensErro.Add("025", "Encaminhamento a autorização não permitido:O resultado da Autenticação da transação não permite a solicitação de Autorização");
            mensagensErro.Add("030", "Status inválido para captura:O status da transação não permite captura");
            mensagensErro.Add("031", "Prazo de captura vencido:Flag de autorização automática incompatível com a forma de pagamento solicitada");
            mensagensErro.Add("032", "Valor de captura inválido:O valor solicitado para captura não é válido");
            mensagensErro.Add("033", "Falha ao capturar:Não foi possível realizar a captura");
            mensagensErro.Add("040", "Prazo de cancelamento vencido:O cancelamento não pode ser realizado, pois o prazo está vencido");
            mensagensErro.Add("041", "Status não permite cancelamento:O atual status da transação não permite cancelamento");
            mensagensErro.Add("042", "Falha ao cancelar:Não foi possível realizar o cancelamento");
            mensagensErro.Add("097", "Sistema indisponível:Não foi possível realizar o cancelamento");
            mensagensErro.Add("098", "Timeout:A aplicação não respondeu dentro de 25 segundos");
            mensagensErro.Add("099", "Erro inesperado:Falha no sistema");

            return mensagensErro[codigoErro];

        }
        public static RespostaRequisicao Parse(string resultadoXMLTexto)
        {
            var resultadoXML = new XmlDocument();
            resultadoXML.LoadXml(resultadoXMLTexto);
            var noErro = resultadoXML.GetElementsByTagName("erro");

            if (noErro.Count == 0)
                return ProcessarSucesso(resultadoXML);
            else
                return ProcessarErro(resultadoXML);

        }
    }


}
